package com.example.demo.controller;

import com.example.demo.model.UserInfo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import java.io.File;
import java.io.IOException;
import java.util.UUID;

/**
 * Created with IntelliJ IDEA.
 * Description:
 * User: H_tao_X
 * Date: 2022-07-20
 * Time: 15:25
 */

/**
 * 一: 实现用户和程序之间的映射：
 * 三种方式：
 * 1.@RequestMapping 既支持 Post 和 Get
 * 2.@PostMapping 只支持 Post
 * 3.@GetMapping 只支持 Get
 */

// 方法1：使用 RequestMapping
    // RequestMapping 特征：
    // 既能修饰类，也能修饰方法
    // 默认情况下，既支持 post 也能 支持 get

/**
 * 方法1：@RequestMapping 既可以支持 Post 也能支持 Get 请求
 */
@Slf4j
@Controller
@RequestMapping("/user") // 类上面的 RequestMapping 可以省略
@ResponseBody // 作用： 表示的是返回一个非静态页面的数据（不加就404）
public class UserController {

    // 从配置文件中读取图片的保存路径
    @Value("${img.path}")
    private String imgPath;
    @RequestMapping("/sayHi") // 路由地址
    public String sayHi(HttpServletRequest request) {
        return "你好，世界" + request.getParameter("name");// 获取name参数
    }

    /**
     * @RequestMapping 扩展，method 后面可以选择支持的请求类型
     * @return
     */
    // @RequestMapping扩展：这样设置，只支持某一类型的请求
    @RequestMapping(method = RequestMethod.POST,value = "sayHi2")
    public String sayHi2() {
        return "Hello,World";
    }

    /**
     * 方法2
     * @PostMapping 只支持 Post 类型的访问方式
     * @return
     */
    @PostMapping("/sayHi3")
    public String sayHi3() {
        return "你好，世界3";
    }

    /**
     * 方法3
     */
    @GetMapping("/sayHi4")
    public String sayHi4() {
        return "你好，世界3";
    }


    /**
     * 二: 获取用户请求参数
     */

    /**
     * 2.1 获取单个参数
     */
    // 两种命名方式 getUserById | findUserById
    @RequestMapping("/getuserbyid") // 理由全部小写，规范
    public UserInfo getUserById(Integer id) { // 通过Id获取 参数 // 也可以 int id
        // 最好是 Integer id，包装类
        // 不查数据库，伪代码，返回用户对象
        UserInfo userInfo = new UserInfo();
        userInfo.setId(id);
        userInfo.setUsername("(๑′ᴗ‵๑)Ｉ Lᵒᵛᵉᵧₒᵤ❤");
        userInfo.setPassword("707703");
        userInfo.setAge(22);
        return userInfo;
    }

    /**
     * 2.2 获取多个参数
     */
    @RequestMapping("/login")
    public String login(String username,String password) {
        return "用户名: " + username + "| 密码: " + password;
        // 输入 url 后，页面显示： 用户名和密码为空
        // http://localhost:8080/user/login?name=zhangsan&password=123
        // 设置内容
    }

    /**
     * 2.3 获取对象
     * 这个牛逼，直接可以在前端直接填充
     * http://localhost:8080/user/reg?id=1&username=zhangsan
     * 最牛逼的是，返回对象的话，可以自己填充
     */
    @RequestMapping("/reg")
    public String reg(@RequestBody UserInfo userInfo) { // 加上@RequsetBody 可以回去JSON格式的对象
        return "用户信息: " + userInfo;
    }

    // 扩展功能：参数重命名，前端用前端的，后端用后端的
    // 前端用的名字你觉得很low，你可以自己重命名
    /**
     * @RequestParm
     */

    // http://localhost:8080/user/login?name=admin&password=admin
    // 比如在 login 下面，前端给你个 name 叫做 admin，你后端是拿不到的
    // 如果这个时候 前端不和你沟通，你可以选择重命名
    @RequestMapping("/login1")
    public String login1(@RequestParam("name") String username,String password) {
        return "用户名: " + username + "| 密码: " + password;
        // 输入 url 后，页面显示： 用户名和密码为空
        // http://localhost:8080/user/login?name=zhangsan&password=123
        // 设置内容
    }

    /**
     * @RequestParm 注意事项：如果在参数中添加 @RequestParm 注解，那么前端
     * 一定要传入参数
     */


    // URL：http（s）://xxx?yyy  ？前面那部分叫做 url部地址分，？之后为参数部分

    /**
     * 2.5 从 URL 地址中获取参数(不是URL 地址中的参数部分获取参数)
     * 这个有意思，可以，牛逼，puLs
     * @PathVariable
     * "/hero/{id}/{name}" hero是url地址，后面大括号里面的是参数
     * 依靠注解才能搞定
     */

    @RequestMapping("/hero/{id}/{name}")
    public String  getHeroInfo(@PathVariable Integer id,@PathVariable String name) {
        return  "ID: " + id +"Name: " + name;
    }


    /**
     * 2.6 使用 PostMan 模拟上传文件
     * @param uid
     * @param file
     * @return
     */

    @RequestMapping("/upimg")
    public boolean upImg(Integer uid, @RequestPart("img")MultipartFile file) {
        boolean result = false;

        // 1. 目录 = imgpath,生产环境中已经配置
        // 2. 图片名称（图片名不能重复）[时间戳/UUID]
        // 3. 获取原上传图片的格式

        String fixName = file.getOriginalFilename(); // 得到原图片名称
        fixName = fixName.substring(fixName.lastIndexOf("."));// 从文件命最后一个点
        // 开始截---》 得到图片后缀 png
        fixName = UUID.randomUUID().toString() + fixName;
        // 保存图片到本地目录
        try {
            file.transferTo(new File(imgPath + fixName));//进行拼接
            result = true;
        } catch (IOException e) {
            log.error("上传图片失败： " + e.getMessage());
        }
        return result;
    }

    /**
     * 扩充功能： 不同运行平台的配置文件设置
     * 1.新建不同平台的配置文件
     * 命名规则 application-平台.yml(properties)
     * 2.在主配件文件中设置配置文件
     */

    /**
     * 2.7 获取Cookie
     */
    // 第一种实现方式
    @RequestMapping("/cookie")
    public void getCookie(HttpServletRequest request) {
        // 得到全部的 cookie
        Cookie[] cookies = request.getCookies();
        for(Cookie item:cookies) {
            log.info("Cookie key :" + item.getName() + "" +
                    "| cookie Value: " + item.getValue());
        }
    }

    // 第二种获取方式：使用 @CookieValue 注解实现
    @RequestMapping("/cookie2")
    public String getCookie2(@CookieValue("bit") String cookie) {
        return "Cookie Value: " + cookie;
    }

    /**
     *  获取 Head
     */

    // 方法一
    @RequestMapping("/getua")
    public String getHead(HttpServletRequest request) {
        return "headr: " + request.getHeader("User-Agent");
    }

    // 方法二
    @RequestMapping("/getua2")
    public String getHead2(@RequestHeader("User-Agent") String userAgent) {
        return "header: " + userAgent;
    }

    /**
     * 2.9 存储和获取 Session
     * 存储 Servlet 和 SpringMvc 的操作方式是一样的
     */
    // 存储 Session
    @RequestMapping("/setsess")
    public boolean setSession(HttpServletRequest request) {
        boolean resulet = false;
        // 1. 得到HttpSession
        HttpSession session = request.getSession(true);// 如果没有会话就创建会话
        // 2. 使用 setAtt 设置值
        session.setAttribute("userinfo","userinfo"); // Value
        resulet = true;
        return resulet;
    }

    // 获取 Session 方法一（Servelet 模式）：
    @RequestMapping("/getsess")
    public String getSession(HttpServletRequest request) {
        String result = null;
        // 1.得到 HttpSession 对象
        HttpSession session = request.getSession(false);// false=如果有会话就使用，没有不创建
        // 2. getAt 得到Session 信息
        if(session != null && session.getAttribute("userinfo") != null) {
            result = (String) session.getAttribute("userinfo");
        }

        return result;
    }

    // 获取 Session 方式二：
    @RequestMapping("/getsess2")
    public String getSession2(@SessionAttribute(value = "userinfo",required = false)String userinfo) {
        return "会话： " + userinfo;
    }




}
